﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using NS_Client.Data;

namespace NS_Client
{
    class Parser
    {
        const char MESSAGE_SPLIT = '&';

        private static string ParseMessage(string cmd, KeyValuePair<string, string>[] parameters)
        {
            if (parameters.Length == 0) return "";

            string message = string.Empty;

            message += Protocol.Keys.ProtocolCmd + "=" + cmd;

            for (int i = 0; i < parameters.Length; i++)
            {
                message += MESSAGE_SPLIT;
                message += parameters[i].Key + "=" + parameters[i].Value;
            }

            return message;
        }

        public static string Build_LogIn(string username, string password)
        {
            KeyValuePair<string, string>[] Credentials = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.Username, username), 
                                                             new KeyValuePair<string, string>(Protocol.Keys.Password, GetMD5Hash(password))
                                                         };
            return ParseMessage(Protocol.Cmd_Values.Login, Credentials);
        }

        public static string Build_GetUserData(string LoginKey, bool IsCurrentUser, string Username)
        {
            KeyValuePair<string, string>[] UserData = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey), 
                                                             new KeyValuePair<string, string>("IsCurrentUser", "NS_CURRENTUSER"), 
                                                             new KeyValuePair<string, string>(Protocol.Keys.Username, Username),                                                            
                                                         };
            return ParseMessage("RequestUserData", UserData);
        }

        private static string GetMD5Hash(string message)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider ServiceCrypto = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] CrypArray = Encoding.UTF8.GetBytes((string)message);
            CrypArray = ServiceCrypto.ComputeHash(CrypArray);
            System.Text.StringBuilder CrpytString = new System.Text.StringBuilder();

            foreach (byte Glyph in CrypArray)
            {
                CrpytString.Append(Glyph.ToString("x2").ToLower());
            }
            return CrpytString.ToString();
        }


        public static string Build_PollChat(string LoginKey)
        {
            KeyValuePair<string, string>[] PollChat = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey), 
                                                         };
            return ParseMessage(Protocol.Cmd_Values.PollChat, PollChat);
        }

        public static string Build_ChatMessage(string LoginKey, string Message)
        {
            KeyValuePair<string, string>[] ChatMsgStr = {
                                                            new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey),
                                                            new KeyValuePair<string, string>(Protocol.Keys.ChatText, Message),
                                                        };
            return ParseMessage(Protocol.Cmd_Values.SendChatMessage, ChatMsgStr);
        }

        public static string Build_UploadAttempt(string LoginKey, string softwareID, string VersionNumber)
        {
            KeyValuePair<string, string>[] AttemptStr = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey), 
                                                             new KeyValuePair<string, string>("NS_SOFTWAREID", softwareID),
                                                             new KeyValuePair<string, string>("NS_VERSION", VersionNumber)
                                                         };

            return ParseMessage(Protocol.Cmd_Values.FileUploadRequest, AttemptStr);
        }

        public static string Build_QueryContentList(string LoginKey)
        {
            KeyValuePair<string, string>[] QuertyContentListStr = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey),
                                                         };

            return ParseMessage(Protocol.Cmd_Values.RequestStoreSoftwareList, QuertyContentListStr);
        }

        public static string Build_RequestDownload(string softwareID, string LoginKey)
        {
            KeyValuePair<string, string>[] DownloadRequestStr = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, LoginKey),
                                                             new KeyValuePair<string, string>("SoftwareVersionID", softwareID)
                                                         };

            return ParseMessage(Protocol.Cmd_Values.DownloadSoftware, DownloadRequestStr);
        }

        public static string Build_CreateContentDescription(string loginKey, string name, string description)
        {
            KeyValuePair<string, string>[] CreateContentStr = { 
                                                             new KeyValuePair<string, string>(Protocol.Keys.LoginKey, loginKey),
                                                             new KeyValuePair<string, string>("NS_NAME", name),
                                                             new KeyValuePair<string, string>("NS_DESCRIPTION", description),
                                                             new KeyValuePair<string, string>("NS_CATEGORY", "1")
                                                         };

            return ParseMessage("CreateSoftwareDescription", CreateContentStr);
        }

        public static Dictionary<string, object> ParseResponse(string response)
        {
            Dictionary<string, object> ParsedKeyValPairs = new Dictionary<string, object>();

            if (response == "")
            {
                return ParsedKeyValPairs;
            }

            try
            {
                string[] Params = response.Split('&');

                foreach (string Parameter in Params)
                {
                    string
                        key = Parameter.Substring(0, Parameter.IndexOf('=')),
                        value = Parameter.Substring(Parameter.IndexOf('=') + 1);

                    if (key == Protocol.Keys.Software || key == Protocol.Keys.Messages)
                    {  
                        try
                        {                            
                            List<Dictionary<string, string>> SoftwareList = new List<Dictionary<string, string>>();

                            foreach (string row in value.Split('`'))
                            {
                                Dictionary<string, string> SoftwareDictionary = new Dictionary<string, string>();
                                
                                if (row == "")
                                    continue;

                                foreach (string column in row.Split('|'))
                                {
                                    string
                                    SoftwareColumnKey = column.Substring(0, column.IndexOf('~')),
                                    SoftwareColumnValue = column.Substring(column.IndexOf('~') + 1);

                                    SoftwareDictionary.Add(SoftwareColumnKey, SoftwareColumnValue);
                                }
                                SoftwareList.Add(SoftwareDictionary);
                            }

                            ParsedKeyValPairs.Add(key, SoftwareList);
                            continue;
                        }
                        catch (Exception e) { System.Diagnostics.Debug.WriteLine(e); }
                    } 
                    ParsedKeyValPairs.Add(key, value);
                }

            }
            catch (Exception e) { System.Diagnostics.Debug.WriteLine(e); }

            return ParsedKeyValPairs;
        }
    }
}
